﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Collections.Generic;

namespace ManPowerEngine
{
	/// <summary>
	/// Renderer Base class
	/// </summary>
	public abstract class RendererBase : ComponentBase, IComparable<RendererBase>
	{
		/// <summary>
		/// dimension of this render object
		/// </summary>
		public int Width;
		/// <summary>
		/// dimension of this render object
		/// </summary>
		public int Height;
		/// <summary>
		/// Center of Rotation of this render object, in pixels, relative to the object's dimension
		/// </summary>
		public Vector Pivot;
		/// <summary>
		/// z order of this renderer
		/// </summary>
		public int ZIndex;
		/// <summary>
		/// Render this object on the screen? Turning off visibility will still prepare this image, but won't be shown on the screen.
		/// </summary>
		public bool Visible;
		/// <summary>
		/// The renderable element of this renderer
		/// </summary>
		internal protected FrameworkElement mElement;

		/// <summary>
		/// Initialize the renderer.
		/// </summary>
		/// <param name="width">width</param>
		/// <param name="height">height</param>
		/// <param name="zindex">z-index</param>
		public RendererBase(int width, int height, int zindex)
		{
			Width = width;
			Height = height;
			ZIndex = zindex;
			Pivot = new Vector(0, 0);
			Visible = true;
		}

		/// <summary>
		/// Cleanup render object of this object from the canvas.
		/// </summary>
		/// <param name="canvas">The canvas to be rendered</param>
		internal void CleanUp(Canvas canvas)
		{
			canvas.Children.Remove(mElement);
		}

		/// <summary>
		/// Add render object into the canvas
		/// </summary>
		/// <param name="canvas">The canvas to be rendered</param>
		internal void AddToCanvas(Canvas canvas)
		{
			canvas.Children.Add(mElement);
		}

		/// <summary>
		/// Render this object to the canvas.
		/// </summary>
		/// <param name="canvas">The canvas to be rendered</param>
		/// <param name="absoluteposition">The position of the this object</param>
		internal void UpdateRenderObjects(Canvas canvas, Vector absoluteposition)
		{
			// correct position to the pivot point
			mElement.SetValue(Canvas.LeftProperty, Math.Round(absoluteposition.X));
			mElement.SetValue(Canvas.TopProperty, Math.Round(absoluteposition.Y));
			double rotation = mGameObject.Transform.Rotation;
			if (rotation != 0)
			{
				mElement.RenderTransform = new RotateTransform
				{
					Angle = -rotation,
					CenterX = Pivot.X,
					CenterY = Pivot.Y
				};
			}
			else
			{
				mElement.RenderTransform = null;
			}
			mElement.SetValue(Canvas.ZIndexProperty, ZIndex);
		}

		/// <summary>
		/// get the framework element, reside in this renderer
		/// </summary>
		public FrameworkElement Element
		{
			get
			{
				return mElement;
			}
		}

		#region IComparable<Renderer> Members

		public int CompareTo(RendererBase other)
		{
			return ZIndex - other.ZIndex;
		}

		#endregion
	}
}
